﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Enough.Converter;
using Windows.UI.Xaml;

namespace UnitTests
{
    [TestClass]
    public class ConversionTests
    {
        [TestMethod]
        public void TestCollectionSizeConverters()
        {
            CollectionSizeToVisibilityConverter converter = new CollectionSizeToVisibilityConverter();
            List<string> values = new List<string>();
            Visibility visibility = (Visibility) converter.Convert(values, null, null, null);
            Assert.AreEqual(Visibility.Visible, visibility);
            visibility = (Visibility)converter.Convert(values, null, "reverse", null);
            Assert.AreEqual(Visibility.Collapsed, visibility);
            visibility = (Visibility)converter.Convert(values, null, "0", null);
            Assert.AreEqual(Visibility.Visible, visibility);
            visibility = (Visibility)converter.Convert(values, null, "1", null);
            Assert.AreEqual(Visibility.Collapsed, visibility);
            IEnumerable<string> orderedValues = values.OrderBy(v => v);
            visibility = (Visibility)converter.Convert(orderedValues, null, null, null);
            Assert.AreEqual(Visibility.Visible, visibility);
            visibility = (Visibility)converter.Convert(orderedValues, null, "reverse", null);
            Assert.AreEqual(Visibility.Collapsed, visibility);

            values.Add("hello");

            visibility = (Visibility)converter.Convert(values, null, null, null);
            Assert.AreEqual(Visibility.Collapsed, visibility);
            visibility = (Visibility)converter.Convert(values, null, "0", null);
            Assert.AreEqual(Visibility.Collapsed, visibility);
            visibility = (Visibility)converter.Convert(values, null, "1", null);
            Assert.AreEqual(Visibility.Visible, visibility);
            visibility = (Visibility)converter.Convert(values, null, "reverse", null);
            Assert.AreEqual(Visibility.Visible, visibility);

            orderedValues = values.OrderBy(v => v);
            visibility = (Visibility)converter.Convert(orderedValues, null, null, null);
            Assert.AreEqual(Visibility.Collapsed, visibility);
            visibility = (Visibility)converter.Convert(orderedValues, null, "reverse", null);
            Assert.AreEqual(Visibility.Visible, visibility);
            visibility = (Visibility)converter.Convert(orderedValues, null, "0", null);
            Assert.AreEqual(Visibility.Collapsed, visibility);
            visibility = (Visibility)converter.Convert(orderedValues, null, "1", null);
            Assert.AreEqual(Visibility.Visible, visibility);

            values.Add("world");
            values.Add("again");

            visibility = (Visibility)converter.Convert(values, null, null, null);
            Assert.AreEqual(Visibility.Collapsed, visibility);
            visibility = (Visibility)converter.Convert(values, null, "reverse", null);
            Assert.AreEqual(Visibility.Visible, visibility);

            orderedValues = values.OrderBy(v => v);
            visibility = (Visibility)converter.Convert(orderedValues, null, null, null);
            Assert.AreEqual(Visibility.Collapsed, visibility);
            visibility = (Visibility)converter.Convert(orderedValues, null, "reverse", null);
            Assert.AreEqual(Visibility.Visible, visibility);
            visibility = (Visibility)converter.Convert(orderedValues, null, "3", null);
            Assert.AreEqual(Visibility.Visible, visibility);

            orderedValues = values.Where(v => v == "not there");
            Assert.AreEqual(0, orderedValues.Count());
            visibility = (Visibility)converter.Convert(orderedValues, null, null, null);
            Assert.AreEqual(Visibility.Visible, visibility);
            visibility = (Visibility)converter.Convert(orderedValues, null, "reverse", null);
            Assert.AreEqual(Visibility.Collapsed, visibility);
            visibility = (Visibility)converter.Convert(orderedValues, null, "0", null);
            Assert.AreEqual(Visibility.Visible, visibility);

            orderedValues = values.Where(v => v == "again");
            Assert.AreEqual(1, orderedValues.Count());
            visibility = (Visibility)converter.Convert(orderedValues, null, "0", null);
            Assert.AreEqual(Visibility.Collapsed, visibility);
            visibility = (Visibility)converter.Convert(orderedValues, null, "1", null);
            Assert.AreEqual(Visibility.Visible, visibility);
            visibility = (Visibility)converter.Convert(orderedValues, null, "2", null);
            Assert.AreEqual(Visibility.Collapsed, visibility);

        }

        [TestMethod]
        public void TestDurationConversion()
        {
            TimeSpanConverter converter = new TimeSpanConverter();
            TimeSpan span = TimeSpan.FromMinutes(20);
            object converted = converter.Convert(span, null, null, null);
            Assert.AreEqual("20 minutes", converted );

            DateTime dateTime = DateTime.Now.AddHours(-2);
            span = DateTime.Now - dateTime;
            converted = converter.Convert(dateTime, null, null, null);
            Assert.AreEqual("2 hours", converted);

            span = TimeSpan.FromHours(1);
            converted = converter.Convert(span, null, null, null);
            Assert.AreEqual("1 hours", converted);

            span = TimeSpan.FromSeconds(0);
            converted = converter.Convert(span, null, null, null);
            Assert.AreEqual("0 seconds", converted);

            span = TimeSpan.FromDays(300);
            converted = converter.Convert(span, null, null, null);
            Assert.AreEqual("300 days", converted);

            span = TimeSpan.FromDays(1);
            converted = converter.Convert(span, null, null, null);
            Assert.AreEqual("1 day", converted);


            span = TimeSpan.FromDays(400);
            converted = converter.Convert(span, null, null, null);
            Assert.AreEqual("1 year", converted);

            span = TimeSpan.FromDays(800);
            converted = converter.Convert(span, null, null, null);
            Assert.AreEqual("2 years", converted);
        }

        [TestMethod]
        public void TestNumberToTextConversion()
        {
            NumberToTextConverter converter = new NumberToTextConverter();
            
            Assert.AreEqual("10", converter.Convert(10, null, null, null) );
            Assert.AreEqual("1,000", converter.Convert(1000, null, null, null) );

            Assert.AreEqual("2.50", converter.Convert(2.5, null, null, null));
            Assert.AreEqual("2.5", converter.Convert(2.5, null, 1, null));
            Assert.AreEqual("2.5", converter.Convert(2.53, null, 1, null));
            Assert.AreEqual("2", converter.Convert(2.4, null, 0, null));
            Assert.AreEqual("3", converter.Convert(2.5, null, 0, null));
            Assert.AreEqual("2.0", converter.Convert(2.0, null, 1, null));
            Assert.AreEqual("2.00", converter.Convert(2.0, null, 2, null));
            Assert.AreEqual("2.00", converter.Convert(2.0, null, null, null));
            Assert.AreEqual("200,000.00", converter.Convert(200000.0, null, null, null));
        }

        [TestMethod]
        public void TestStringFormatConversion()
        {
            StringFormatConverter converter = new StringFormatConverter();

            Assert.AreEqual("2.50", converter.Convert(2.5, null, "{0:N2}", null));
            Assert.AreEqual("  rock", converter.Convert("rock", null, "{0,6}", null));
        }

        [TestMethod]
        public void TestTranslationConversion()
        {
            TranslationConverter converter = new TranslationConverter();
            // translation_test is defined in Resources.resw
            Assert.AreEqual("testing BIG!", converter.Convert("BIG", null, "translation_test", null));
            Assert.AreEqual("testing 111!", converter.Convert(111, null, "translation_test", null));
            Assert.AreEqual("testing one!", converter.Convert(1, null, "translation_test", null));
        }

        [TestMethod]
        public void TestComparisonConversion()
        {
            ComparisonToBooleanConverter converter = new ComparisonToBooleanConverter();
            Assert.AreEqual(true, converter.Convert(1, null, "==1", null));
            Assert.AreEqual(true, converter.Convert(1, null, "== 1", null));
            Assert.AreEqual(true, converter.Convert("bla", null, "==bla", null));
            Assert.AreEqual(true, converter.Convert("bla", null, "== bla", null));
            Assert.AreEqual(true, converter.Convert(1, null, ">=1", null));
            Assert.AreEqual(true, converter.Convert(1, null, ">= 1", null));
            Assert.AreEqual(true, converter.Convert(2, null, ">=1", null));
            Assert.AreEqual(true, converter.Convert(2, null, ">= 1", null));
            Assert.AreEqual(true, converter.Convert(1.1, null, ">=1", null));
            Assert.AreEqual(true, converter.Convert(1.1, null, ">= 1", null));
            Assert.AreEqual(true, converter.Convert(1, null, "<=1", null));
            Assert.AreEqual(true, converter.Convert(1, null, "<= 1", null));
            Assert.AreEqual(true, converter.Convert(0, null, "<=1", null));
            Assert.AreEqual(true, converter.Convert(0, null, "<= 1", null));
            Assert.AreEqual(true, converter.Convert(0.99, null, "<=1", null));
            Assert.AreEqual(true, converter.Convert(0.99, null, "<= 1", null));

            Assert.AreEqual(false, converter.Convert(0, null, "==1", null));
            Assert.AreEqual(false, converter.Convert(0, null, "== 1", null));
            Assert.AreEqual(false, converter.Convert("black", null, "==bla", null));
            Assert.AreEqual(false, converter.Convert("black", null, "== bla", null));
            Assert.AreEqual(false, converter.Convert(0.9, null, ">=1", null));
            Assert.AreEqual(false, converter.Convert(0, null, ">= 1", null));
            Assert.AreEqual(false, converter.Convert(-1, null, ">=1", null));
            Assert.AreEqual(false, converter.Convert(0.777882, null, ">= 1", null));
            Assert.AreEqual(false, converter.Convert(0.1, null, ">=1", null));
            Assert.AreEqual(false, converter.Convert(0.9, null, ">= 1", null));
            Assert.AreEqual(false, converter.Convert(1.01, null, "<=1", null));
            Assert.AreEqual(false, converter.Convert(1.2, null, "<= 1", null));
            Assert.AreEqual(false, converter.Convert(1.3, null, "<=1", null));
            Assert.AreEqual(false, converter.Convert(2, null, "<= 1", null));
            Assert.AreEqual(false, converter.Convert(1.99, null, "<=1", null));
            Assert.AreEqual(false, converter.Convert(3, null, "<= 1", null));
        }
    }
}
